package com.uparlange.project.flextris
{
	import flash.geom.Point;

	/**
	 * Represents occupation of pieces in the playfield of the tetris
	 * 
	 * @author Ugo Parlange
	 */ 
	public class Matrice
	{
		/**
		 * Configuration
		 */
		public static const NB_SQUARE_WIDTH : int = 10;
		public static const NB_SQUARE_HEIGHT : int = 22;
		
		/**
		 * Number of columns
		 */ 
		private var columnCount : int;
		
		/**
		 * Number of lines
		 */ 
		private var lineCount : int;
		
		/**
		 * The matrice
		 */ 
		private var matriceArray : Array;
		
		/**
		 * Constructor
		 * 
		 * @param aColumnCount int, the number of columns
		 * @param aLineCount int, the number of lines
		 */ 
		public function Matrice(aColumnCount : int = NB_SQUARE_WIDTH, aLineCount : int = NB_SQUARE_HEIGHT) {
			super();
			columnCount = aColumnCount;
			lineCount = aLineCount;
			raz();
		}
		
		/**
		 * Initialize the matrice
		 */ 
		public function raz() : void {
			matriceArray = new Array();
			for (var lineIndex : int = 0; lineIndex < lineCount; lineIndex++) {
				matriceArray[lineIndex] = new Array();
				for (var columnIndex : int = 0; columnIndex < columnCount; columnIndex++) {
					matriceArray[lineIndex][columnIndex] = 0;
				} 
			}
		}
		
		/**
		 * Check if cell is free
		 * 
		 * @param aPoint Point, the position to check
		 * 
		 * @return Boolean, true if the cell is free
		 */ 
		public function isFree(aPoint : Point) : Boolean {
			if(aPoint.x < 0 || aPoint.x >= columnCount) return false;
			if(aPoint.y < 0 || aPoint.y >= lineCount) return false;
			return (matriceArray[aPoint.y][aPoint.x] == 0 ? true : false);
		}
		
		/**
		 * Check if a list of cells are free
		 * 
		 * @param aPoints Array, the list of cells to check
		 * 
		 * @return Boolean, true if space available
		 */ 
		public function hasSpace(aPoints : Array) : Boolean {
			for each(var point : Point in aPoints) {
				if(!isFree(point)) {
					return false;
				}
			}
			return true;
		}
		
		/**
		 * Book a cell
		 * 
		 * @param aPoint Point, the position to book
		 */ 
		public function book(aPoint : Point) : void {
			matriceArray[aPoint.y][aPoint.x] = 1;
		}
		
		/**
		 * Unbook a cell
		 * 
		 * @param aPoint Point, the position to unbook
		 */ 
		public function unBook(aPoint : Point) : void {
			matriceArray[aPoint.y][aPoint.x] = 0;
		}
		
		/**
		 * Gets list of full lines (all cells are booked)
		 * 
		 * @return Array, the line indexes
		 */ 
		public function getCompleteLines() : Array {
			var cl : Array = new Array();
			for (var lineIndex : int = 0; lineIndex < lineCount; lineIndex++) {
				if(lineIsComplete(lineIndex)) {
					cl.push(lineIndex);
				}
			}
			return cl;
		}
		
		/**
		 * Check if a line is full (all cells are booked)
		 * 
		 * @param aLineIndex int, the line index to check
		 * 
		 * @return Boolean, true is line is full
		 */ 
		private function lineIsComplete(aLineIndex : int) : Boolean {
			for (var columnIndex : int = 0; columnIndex < columnCount; columnIndex++) {
				if(isFree(new Point(columnIndex, aLineIndex))) {
					return false;
				}
			}
			return true;
		}
	}
}